import mongoose, { Document, Schema } from 'mongoose';
import bcrypt from 'bcryptjs';

export interface IUser extends Document {
  id: string;
  name: string;
  email: string;
  password?: string;
  age?: number;
  roles: any[string];
  isActive: boolean;
  lastLogin?: Date;
  createdAt: Date;
  sex?: number,
  updatedAt: Date;
  createdBy: mongoose.Schema.Types.ObjectId,
  updatedBy: mongoose.Schema.Types.ObjectId,
}

const userSchema = new Schema<IUser>({
  name: {
    type: String,
    required: [true, '姓名是必填项'],
    trim: true,
    minlength: [2, '姓名至少需要2个字符'],
    maxlength: [50, '姓名不能超过50个字符']
  },
  sex: {
    type: Number,
    default: 2
  },
  email: {
    type: String,
    required: [true, '邮箱是必填项'],
    unique: true,
    lowercase: true,
    trim: true,
    match: [/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/, '请输入有效的邮箱地址']
  },
  password: {
    type: String,
    required: [true, '密码是必填项'],
    minlength: [6, '密码至少需要6个字符']
  },
  age: {
    type: Number,
    min: [0, '年龄不能小于0'],
    max: [150, '年龄不能超过150']
  },
  roles: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Role',
    }
  ],
  isActive: {
    type: Boolean,
    default: true
  },
  createdBy: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
  },
  updatedBy: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
  },
  lastLogin: {
    type: Date,
    default: () => new Date()
  }
}, {
  timestamps: true // 自动添加 createdAt 和 updatedAt
});

// 创建索引
userSchema.index({ createdAt: -1 });

// 虚拟字段（不存储在数据库中）
userSchema.virtual('displayName').get(function () {
  return `${this.name} (${this.email})`;
});

// 实例方法
userSchema.methods.toJSON = function () {
  const user = this.toObject();
  delete user.password; // 移除密码字段
  return user;
};

// 静态方法
userSchema.statics.findByRole = function (role: string) {
  return this.find({ role, isActive: true });
};

// 中间件 - 密码加密
userSchema.pre('save', async function (next) {
  if (this.isModified('password') && this.password) {
    try {
      const saltRounds = 12;
      this.password = await bcrypt.hash(this.password, saltRounds);
    } catch (error) {
      return next(error as Error);
    }
  }
  next();
});

// 实例方法 - 验证密码
userSchema.methods.comparePassword = async function (candidatePassword: string): Promise<boolean> {
  if (!this.password) return false;
  return bcrypt.compare(candidatePassword, this.password);
};

// 实例方法 - 验证是否激活
userSchema.methods.verifyIsActive = async function (): Promise<boolean> {
  return this.isActive === true;
};

export const UserModel = mongoose.model<IUser>('User', userSchema);